﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Translate;
using System.Windows.Forms;
using System.Web;
using Google.API.Translate;



using System.Text.RegularExpressions;
//using ulif;

namespace AlexTranslator
{
    public class TextTools
    {

        

        public static string ExpandLinkText(string text)
        {
            string resultString = null;
            try
            {
                Regex regexObj = new Regex(@"\[\[(.+?)(\|.+?)?]](\w{0,20})");
                //(@"\[\[(.+?)(\|.+?)?]]");
                resultString = regexObj.Replace(text,
                    new MatchEvaluator(delegate(Match match)
                    {
                        string linkText = match.Groups[2].Value;
                        if (linkText.Trim() == "" &&
                            !match.Groups[1].Value.Contains(":")) // making replacement
                        {
                            string concreteLink = match.Groups[1].Value;
                            Regex yearRx = new Regex(@"(\d{2,4}) год");

                            if (concreteLink.Contains(" год") &&
                                yearRx.IsMatch(concreteLink))
                            {

                                return string.Concat("[[", yearRx.Match(concreteLink)
                                    .Groups[1], "]]", " год", match.Groups[3].Value);

                            }
                            else
                            {
                                if (match.Groups[3].Value.Trim() != "")
                                {

                                    return string.Concat("[[", concreteLink, "|",
                                        concreteLink + match.Groups[3].Value, "]]");
                                    //"[[" + matches[i].Groups[2].Value+"]]"
                                }
                            }
                        }
                        return match.Value;
                    }
                        ));
            }
            catch (ArgumentException )
            {
                throw;
            }
            return resultString;
        }

        public readonly static string linksSeparationMarker = "__links__";
        public static string ReplaceLinksWithText(string text)
        {
            if (text.Contains(linksSeparationMarker))
                return text;

            Regex wikiLinkRE = //new Regex(@"\[\[(.+?)(\|((?!]).)+?){1}]]"); // only links with text
                new Regex(@"\[\[(.+?)(\|.+?)?]]"); // all links
            MatchCollection matches = wikiLinkRE.Matches(text);
            //string result;

            //for (int i = 0; i < matches.Count; i++) //groups [0] whole link; 
            //Groups[1] - the concrete link; Groups[2] link text
            //    if (exclLinks.Contains(matches[i].Groups[1].Value) == false &&
            //        exclLinks.Contains(matches[i].Groups[1].Value.TrimStart(':')) == false)

            List<string> linksReplaced = new List<string>();
            for (int i = 0; i < matches.Count; i++) //groups [0] whole link; 
            //Groups[1] - the concrete link; Groups[2] link text
            {
                string linkText = matches[i].Groups[2].Value;


                if (linkText.Trim() != "" && !matches[i].Groups[1].Value.Contains(":")) // making replacement
                {


                    string concreteLink = matches[i].Groups[1].Value;
                    if (concreteLink.Trim() == "*")
                        return text; //text is already processed before.
                    string wholeLink = matches[i].Groups[0].Value; //whole link [[Alex|Sashunya]] 
                    //string replacementText = wholeLink.Replace(concreteLink, "*");
                    text = text.Replace(wholeLink, "[[* " + (linksReplaced.Count + 1)+" " + matches[i].Groups[2].Value + "]]");

                    linksReplaced.Add(concreteLink);
                }
            }

            text += "\n"+ linksSeparationMarker + linksReplaced.Count + " links=="; //"\n======";
            foreach (string link in linksReplaced)
            {
                text += "\n=" + link + "=";
            }
            Logger.Write(linksReplaced.Count + " links replaced");

            return text;
        }

        public static string BackReplacementLinksWithText(string text)
        {
            if(!text.Contains(linksSeparationMarker))
                return text;

            int beginIndex;
            List<string> linksArr;
            GetUnprocessedLinksArray(text, out beginIndex, out linksArr);
            Logger.Write("Links in links section found: " + linksArr.Count);


            text = text.Remove(beginIndex);

            Regex wikiLinkRE = new Regex(@"\[\[(.+?)(\|.+?)?]]");
            MatchCollection matches = wikiLinkRE.Matches(text);

            int replacingCounter = 0; //replacingCounter++;
            for (int i = 0; i < matches.Count; i++) //groups [0] whole link; 
            //Groups[1] - the concrete link; Groups[2] link text
            {
                string linkText = matches[i].Groups[2].Value;


                if (linkText.Trim() != "" && !matches[i].Groups[1].Value.Contains(":")) // making replacement
                {
                    string concreteLink = matches[i].Groups[1].Value;
                    if (concreteLink.Trim().Contains("*"))
                    {
                        string wholeLink = matches[i].Groups[0].Value; //whole link [[Alex|Sashunya]] 
                        string replacementText = wholeLink.Replace(concreteLink, linksArr[replacingCounter]);
                        text = text.Replace(wholeLink, replacementText);
                        replacingCounter++;
                    }
                }
            }
            Logger.Write("Links back replaced:" + (replacingCounter + 1));
            if (replacingCounter != linksArr.Count)
            {
                string msg = string.Format("Error during links BackReplacing. Links={0}, Links replaced = {1}", linksArr.Count, replacingCounter);
                Logger.Write(msg);
                MessageBox.Show(msg);
                throw new BackReplacementException();
            }

            return text;
        }

        public static void GetUnprocessedLinksArray(string text, out int beginIndex, out List<string> linksArr)
        {
            beginIndex = text.IndexOf(linksSeparationMarker);
            string links = "";
            if (beginIndex != -1)
                links = text.Substring(beginIndex);
            else
            {
                MessageBox.Show("it seems linksSeparationMarker( = '\n======'). is wrong");
                throw new IndexOutOfRangeException("it seems linksSeparationMarker( = '\n======'). is wrong");
            }

            //List<string> 
            linksArr = new List<string>(links.Split(new char[] { '\n', '\r', '=' }, StringSplitOptions.RemoveEmptyEntries));
            //Split(new[] { ',' }, 2);
            linksArr.RemoveAt(0); // we eliminate line "=====7 links==="
            linksArr = new List<string>(linksArr.Select((elem, i) => elem).Where(n => (n != " ")));
        }

        public static string ReplaceWebLinks(string text, bool forward, Dictionary<string, string> emptyDic)
        {
            if (forward)
            {
                Random rnd = new Random();
                string rndStr = "";
                string resultString = null;
                try
                {
                    resultString = Regex.Replace(text, @"([a-z0-9_\-]{1,5}:\/\/)?(([a-z0-9_\-]{1,}):([a-z0-9_\-]{1,})\@)?((www\.)|([a-z0-9_\-]{1,}\.)+)?([a-z0-9_\-]{3,})(\.[a-z]{2,4})(\/([a-z0-9_\-]{1,}\/)+)?([a-z0-9_\-]{1,})?(\.[a-z]{2,})?(\?)?(((\&)?[a-z0-9_\-]{1,}(\=[a-z0-9_\-]{1,})?)+)?",
                        new MatchEvaluator(delegate(Match m)
                        {


                            while (text.Contains(rndStr) || emptyDic.ContainsKey(rndStr))
                                rndStr = rnd.Next().ToString();
                            emptyDic.Add(rndStr, m.Value);
                            return rndStr;

                        }
                                ),
                        RegexOptions.Singleline | RegexOptions.IgnoreCase);
                }
                catch (ArgumentException)
                {
                    // Syntax error in the regular expression
                }
                return resultString;
            }
            else
            {
                foreach (KeyValuePair<string, string> pair in emptyDic)
                {
                    text = text.Replace(pair.Key, pair.Value);
                }
                return text;
            }
            //return "";
        }

        public static string ReplaceRefs(string text, bool forward, Dictionary<string,string> emptyDic)
        {
            if (forward)
            {
                Random rnd = new Random();
                string rndStr = "";
                string resultString = null;
                try
                {
                    resultString = Regex.Replace(text, "<Ref[^>]*>(.*?)</Ref>",
                        new MatchEvaluator(delegate(Match m)
                            {


                                while (text.Contains(rndStr)|| emptyDic.ContainsKey(rndStr))
                                    rndStr = rnd.Next().ToString();
                                emptyDic.Add(rndStr, m.Value);
                                return rndStr;

                            }
                                ),
                        RegexOptions.Singleline | RegexOptions.IgnoreCase);
                }
                catch (ArgumentException )
                {
                    // Syntax error in the regular expression
                }
                return resultString;
            }
            else
            {
                foreach (KeyValuePair<string, string> pair in emptyDic)
                {
                    text = text.Replace(pair.Key, pair.Value);
                }
                return text;
            }
            //return "";
        }

        
    }
}
